#coding=utf-8

__doc__='''


'''

import sys,os,urllib,re
import threading, Queue, time, traceback


WORK_INTERVAL = 1 

# Globals (start with a capital letter)
Qin  = Queue.Queue( )
Qout = Queue.Queue( )
Qerr = Queue.Queue( )
Pool = [  ]
def report_error( ):
    ''' we "report" errors by adding error information to Qerr '''
    Qerr.put(sys.exc_info( )[:2])
    print sys.exc_info( )[1]
def get_all_from_queue(Q):
    ''' generator to yield one after the others all items currently
        in the Queue Q, without any waiting
    '''
    try:
        while True:
            yield Q.get_nowait( )
    except Queue.Empty:
        raise StopIteration
def do_work_from_queue( ):
    ''' the get-some-work, do-some-work main loop of worker threads '''
    while True:
        time.sleep(WORK_INTERVAL)
        command, item = Qin.get( )       # implicitly stops and waits
        if command == 'stop':
            break
#        try:
        elif command == 'process':
#                result = 'new' + item
#            try:
            time.sleep(.3)
            callableA,args = item[0],item[1]
            callableA(*args)
#            except Exception , ex:
#                traceback.print_exc(file=sys.stdout)
        else:
            raise ValueError, 'Unknown command %r' % command

def make_and_start_thread_pool(number_of_threads_in_pool=5, daemons=True):
    ''' make a pool of N worker threads, daemonize, and start all of them '''
    for i in range(number_of_threads_in_pool):
         new_thread = threading.Thread(target=do_work_from_queue)
         new_thread.setDaemon(daemons)
         Pool.append(new_thread)
         new_thread.start( )
def request_work(data, command='process'):
    ''' work requests are posted as (command, data) pairs to Qin '''
    Qin.put((command, data))

def get_result( ):
    return Qout.get( )     # implicitly stops and waits
def show_all_results( ):
    for result in get_all_from_queue(Qout):
        print 'Result:', result
def show_all_errors( ):
    for etyp, err in get_all_from_queue(Qerr):
        print 'Error:', etyp, err

def stop_and_free_thread_pool( ):
    # order is important: first, request all threads to stop...:
    for i in range(len(Pool)):
        request_work(None, 'stop')
    # ...then, wait for each of them to terminate:
    for existing_thread in Pool:
        existing_thread.join( 10 )
    # clean up the pool from now-unused thread objects
    del Pool[:]

    
    
        
        
#for i in ('_ba', '_be', '_bo'): request_work(i)
#make_and_start_thread_pool( )
#stop_and_free_thread_pool( )
#show_all_results( )
#show_all_errors( )
    